import { ChatContext } from '@/app/chat-context';
import { apiInterceptors, getChatFeedBackSelect } from '@/client/api';
import { getLexiconByApp, caseSave } from '@/client/api/domainThesaurus';
import { useRequest } from 'ahooks';
import useSummary from '@/hooks/use-summary';
import { FeedBack, IChatDialogueMessageSchema } from '@/types/chat';
import { STORAGE_INIT_MESSAGE_KET, getInitMessage } from '@/utils';
import { CopyOutlined, RedoOutlined, ContainerOutlined } from '@ant-design/icons';
import { useAsyncEffect } from 'ahooks';
import { Modal, Tooltip, message, Popover,Alert,Button } from 'antd';
import classNames from 'classnames';
import copy from 'copy-to-clipboard';
import { cloneDeep } from 'lodash';
import { useSearchParams } from 'next/navigation';
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';

import MyEmpty from '../common/MyEmpty';
import CompletionInput from '../common/completion-input';
import AgentContent from './agent-content';
import ChatContent from './chat-content';
import ChatFeedback from './chat-feedback';
import { renderModelIcon } from './header/model-selector';
import MonacoEditor from './monaco-editor';
import { useRouter } from 'next/router';
import { ChatContentContext } from '@/pages/chat';

type Props = {
  messages: IChatDialogueMessageSchema[];
  onSubmit: (message: string, otherQueryBody?: Record<string, any>) => Promise<void>;
  onFormatContent?: (content: any) => any; // Callback for extracting thinking part
};

const Completion = ({ messages, onSubmit, onFormatContent }: Props) => {
  const { dbParam, currentDialogue, scene, model, refreshDialogList, chatId, agent, docId } = useContext(ChatContext);
  const { t } = useTranslation();
  const searchParams = useSearchParams();

  const flowSelectParam = (searchParams && searchParams.get('select_param')) ?? '';
  const spaceNameOriginal = (searchParams && searchParams.get('spaceNameOriginal')) ?? '';

  const [isLoading, setIsLoading] = useState(false);
  const [jsonModalOpen, setJsonModalOpen] = useState(false);
  const [showMessages, setShowMessages] = useState(messages);
  const [jsonValue, setJsonValue] = useState<string>('');
  const [select_param, setSelectParam] = useState<FeedBack>();

  const scrollableRef = useRef<HTMLDivElement>(null);

  const { appInfo } = useContext(ChatContentContext)
  const router = useRouter();
  // 新增：Alert 显示状态
  const [showAlert, setShowAlert] = useState(false);
  const alertTimerRef = useRef<NodeJS.Timeout | null>(null);

  // const incremental = useMemo(() => scene === 'chat_flow', [scene]);
  const isChartChat = useMemo(() => scene === 'chat_dashboard', [scene]);

  const summary = useSummary();
  const paramKey: string[] = useMemo(() => {
    return appInfo.param_need?.map(i => i.type) || [];
  }, [appInfo.param_need]);

  const selectParam = useMemo(() => {
    switch (scene) {
      case 'chat_agent':
        return agent;
      case 'chat_excel':
        return currentDialogue?.select_param;
      case 'chat_flow':
        return flowSelectParam;
      default:
        return spaceNameOriginal || dbParam;
    }
  }, [scene, agent, currentDialogue, dbParam, spaceNameOriginal, flowSelectParam]);

  const handleChat = async (content: string) => {
    if (isLoading || !content.trim()) return;
    if (scene === 'chat_agent' && !agent) {
      message.warning(t('choice_agent_tip'));
      return;
    }
    const tableSetId = appInfo?.param_need?.filter(item => item.type === 'table_set')[0]?.value;  //表集合id
    try {
      setIsLoading(true);
      await onSubmit(content, {
        select_param: selectParam ?? '',
        ...(paramKey.includes('table_set') && { table_set_id: tableSetId }),
      });
    } finally {
      setIsLoading(false);
    }
  };

  // Process message content - if onFormatContent is provided and this is a dashboard chat,
  // we'll extract the thinking part from vis-thinking code blocks
  const processMessageContent = (content: any) => {
    if (isChartChat && onFormatContent && typeof content === 'string') {
      return onFormatContent(content);
    }
    return content;
  };

  const [messageApi, contextHolder] = message.useMessage();

  const onCopyContext = async (context: any) => {
    // If we have a formatting function and this is a string, apply it before copying
    const contentToCopy =
      isChartChat && onFormatContent && typeof context === 'string' ? onFormatContent(context) : context;

    const pureStr = contentToCopy?.replace(/\trelations:.*/g, '');
    const result = copy(pureStr);
    if (result) {
      if (pureStr) {
        messageApi.open({ type: 'success', content: t('copy_success') });
      } else {
        messageApi.open({ type: 'warning', content: t('copy_nothing') });
      }
    } else {
      messageApi.open({ type: 'error', content: t('copy_failed') });
    }
  };

  const handleRetry = async () => {
    if (isLoading || !docId) {
      return;
    }
    setIsLoading(true);
    await summary(docId);
    setIsLoading(false);
  };

  useAsyncEffect(async () => {
    const initMessage = getInitMessage();
    if (initMessage && initMessage.id === chatId) {
      await handleChat(initMessage.message);
      refreshDialogList();
      localStorage.removeItem(STORAGE_INIT_MESSAGE_KET);
    }
  }, [chatId]);

  useEffect(() => {
    let tempMessage: IChatDialogueMessageSchema[] = messages;
    if (isChartChat) {
      tempMessage = cloneDeep(messages).map(item => {
        if (item?.role === 'view') {
          if (typeof item?.context === 'string') {
            // Try to parse JSON first
            try {
              item.context = JSON.parse(item.context);
            } catch {
              // If JSON parsing fails and we have a formatting function,
              // it might be a vis-thinking block, so process it
              if (onFormatContent) {
                item.context = processMessageContent(item.context);
              }
            }
          }
        }
        return item;
      });
    }
    setShowMessages(tempMessage.filter(item => ['view', 'human'].includes(item.role)));
  }, [isChartChat, messages, onFormatContent]);

  useEffect(() => {
    apiInterceptors(getChatFeedBackSelect())
      .then(res => {
        setSelectParam(res[1] ?? {});
      })
      .catch(err => {
        console.log(err);
      });
  }, []);

  useEffect(() => {
    setTimeout(() => {
      scrollableRef.current?.scrollTo(0, scrollableRef.current.scrollHeight);
    }, 50);
  }, [messages]);

  // 获取app绑定的领域词
  const { data: lexiconData } = useRequest(async () => {
    const [, res] = await apiInterceptors(
      getLexiconByApp({ app_code: appInfo?.app_code ?? scene })
    );
    return res ?? [];
  });

  // 存为案例接口
  const saveCase = async (item,context)=>{
    const historyLastQa = sessionStorage.getItem('history_last_qa') ? JSON.parse(sessionStorage.getItem('history_last_qa')) : {}; //历史对话最后一组问答
    const initMessage = getInitMessage(); // 用户 当前输入 的问题
    // console.log(initMessage)
    const data = {
      name: initMessage?.message || historyLastQa?.question.context,
      lexicon_domain_id: item.id,
      desc:context, 
      app_code: appInfo?.app_code || ''
    }
    
    const res = await caseSave(data);
    if(res.data.success){  
      setShowAlert(true);
      // 5秒后自动关闭
      if (alertTimerRef.current) clearTimeout(alertTimerRef.current);
      alertTimerRef.current = setTimeout(() => setShowAlert(false), 5000);
    }else{
      message.error(res.data.err_msg_zh || res.data.err_msg)
    }
  }

  // 组件卸载时清理定时器
  useEffect(() => {
    return () => {
      if (alertTimerRef.current) clearTimeout(alertTimerRef.current);
    };
  }, []);

  return (
    <>
      {contextHolder}
      <div ref={scrollableRef} className='flex flex-1 overflow-y-auto h-full w-full flex-col'>
        <div className='flex items-center flex-1 flex-col text-sm leading-6 text-slate-900 dark:text-slate-300 sm:text-base sm:leading-7'>
          {showMessages.length ? (
            showMessages.map((content, index) => {
              if (scene === 'chat_agent') {
                return <AgentContent key={index} content={content} />;
              }
              return (
                <ChatContent
                  key={index}
                  content={content}
                  isChartChat={isChartChat}
                  onLinkClick={() => {
                    setJsonModalOpen(true);
                    setJsonValue(JSON.stringify(content?.context, null, 2));
                  }}
                >
                  {content.role === 'view' && (
                    <div className='flex w-full border-t border-gray-200 dark:border-theme-dark'>
                      {scene === 'chat_knowledge' && content.retry ? (
                        <Button onClick={handleRetry}  size="small" type="link">
                          <RedoOutlined />
                          &nbsp;<span className='text-sm'>{t('Retry')}</span>
                        </Button>
                      ) : null}
                      <div className='flex w-full items-center flex-row-reverse'>
                        <ChatFeedback
                          select_param={select_param}
                          conv_index={Math.ceil((index + 1) / 2)}
                          question={
                            showMessages?.filter(e => e?.role === 'human' && e?.order === content.order)[0]?.context
                          }
                          knowledge_space={spaceNameOriginal || dbParam || ''}
                        />
                        <Tooltip title={t('Copy_Btn')}>
                          <Button  onClick={() => onCopyContext(content?.context)}  size="small" type="link">
                            <CopyOutlined />
                          </Button>
                        </Tooltip>
                        <Popover placement='bottom' trigger='hover' content={
                          <div>
                            {(lexiconData || []).length === 0 && (
                              <Alert 
                                message="未设置领域，无法保存案例，请先选择设置 "
                                type="warning"
                                showIcon
                                action={
                                  <Button size="small" type="link" onClick={() => router.push('construct/domainThesaurus')}>
                                    领域
                                  </Button>
                                }              
                              />
                            )}
                            {(lexiconData || []).map((item, idx) => (
                              <div key={item.id || idx} className='text-xs text-gray-500'>
                                { item.name }
                                <Button type="link"  onClick={() => { saveCase(item,content?.context) }}>存为案例</Button>
                              </div>
                            ))}
                          </div>
                        }>
                            <Button size="small" type="link">
                              <ContainerOutlined />
                            </Button>
                        </Popover>

                        { showAlert && (<Alert className="fixed bottom-10 z-50" style={{width:260,left:'45%'}}
                          message="存储成功"
                          type="success"
                          showIcon
                          action={
                            <Button size="small" type="link" onClick={() => router.push('construct/domainThesaurus')}>
                              去看看
                            </Button>
                          }
                          closable
                          onClose={() => setShowAlert(false)}
                        />
                        )}
                      </div>
                    </div>
                  )}
                </ChatContent>
              );
            })
          ) : (
            <MyEmpty description='' />
          )}
        </div>
      </div>
      <div
        className={classNames(
          'relative sticky bottom-0 bg-theme-light dark:bg-theme-dark after:absolute after:-top-8 after:h-8 after:w-full after:bg-gradient-to-t after:from-theme-light after:to-transparent dark:after:from-theme-dark',
          {
            'cursor-not-allowed': scene === 'chat_excel' && !currentDialogue?.select_param,
          },
        )}
      >
        <div className='flex flex-wrap w-full p-4 sm:pt-6 sm:pb-10 items-center'>
          {/* {model && <div className='mr-2 flex'>{renderModelIcon(model)}</div>} */}
          <CompletionInput loading={isLoading} onSubmit={handleChat} handleFinish={setIsLoading} />
        </div>
      </div>
      <Modal
        title='JSON Editor' 
        open={jsonModalOpen}
        width='60%'
        cancelButtonProps={{
          hidden: true,
        }}
        onOk={() => {
          setJsonModalOpen(false);
        }}
        onCancel={() => {
          setJsonModalOpen(false);
        }}
      >
        <MonacoEditor className='w-full h-[500px]' language='json' value={jsonValue} />
      </Modal>
    </>
  );
};

export default Completion;
